package code

import (
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// 很多直接返回的会返回grpc自带的OK，所以ok我们不能自定义
// 很多grpc自己不会抛出的错误我们应该自己重新定义，一些grpc自己会产生的我们也可以自定义一下
// grpc会自己抛出的错误我们应该做转换
// 每个服务可以给1000个错误码的容量
const (
	InvalidArgument   codes.Code = 100001
	Unauthenticated              = 100002
	Unimplemented                = 100003
	UserAlreadyExists            = 100004
	UserNotExists                = 100005
	WrongPassword                = 100006

	Timeout  = 100108
	Canceled = 100109
	Internal = 100110
	Unknown  = 100111
)

func FromError(err error) (codes.Code, string) {
	if nil == err {
		return codes.OK, codes.OK.String()
	}
	s, ok := status.FromError(err)
	//对于不是status包装的非正规错误，直接返回unknown
	if !ok {
		return Unknown, err.Error()
	}

	code := s.Code()
	msg := s.Message()

	//处理grpc自己抛出的错误
	switch code {
	case codes.Canceled:
		return Canceled, msg
	case codes.DeadlineExceeded:
		return Timeout, msg
	case codes.ResourceExhausted, codes.Unavailable, codes.Internal:
		return Internal, msg
	case codes.Unauthenticated:
		return Unauthenticated, msg
	case codes.Unknown:
		return Unknown, msg
	}
	return code, msg
}
